package com.alinesno.cloud.compoment.generate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alinesno.cloud.compoment.generate.generator.AutoGenerator;
import com.alinesno.cloud.compoment.generate.generator.InjectionConfig;
import com.alinesno.cloud.compoment.generate.generator.config.DataSourceConfig;
import com.alinesno.cloud.compoment.generate.generator.config.GlobalConfig;
import com.alinesno.cloud.compoment.generate.generator.config.PackageConfig;
import com.alinesno.cloud.compoment.generate.generator.config.StrategyConfig;
import com.alinesno.cloud.compoment.generate.generator.config.rules.DbType;
import com.alinesno.cloud.compoment.generate.generator.config.rules.NamingStrategy;

/**
 * 代码生成工具类
 * @author LuoAnDong
 * @date 2017年9月16日
 */
public abstract class SelfGenerator {

	public final Logger logger = LoggerFactory.getLogger(this.getClass());

	private  String driverName = null;
	private  String userName = null;
	private  String userPassword = null;
	private  String jdbcUrl = null;
	private  String author = null;
	private  String outputDir = null;

	private DbType dbType = DbType.MYSQL ; /* 数据库类型 */
	private String[] tablePrefix = {} ; /* 表前缀 */
	private String[] tableNames; /* 目标表 */
	private List<String> arr = new ArrayList<String>();
	private String parentPackage = ""; /* 父包名 */
	private String moduleName = ""; /* 模块名 */

	/**
	 * soa模块前缀
	 */
	public String SOA_MODULE_PREFIX = "" ;
	private String abcPath ; 

	/**
	 * <p>
	 * 生成演示
	 * </p>
	 */
	public void generator() {

		initTableName();

		if (tablePrefix == null) {
			logger.debug("table prefix 为空");
			return;
		}
 
		tableNames = new String[arr.size()];
		for (int i = 0; i < arr.size(); i++) {
			tableNames[i] = arr.get(i);
		}

		final AutoGenerator mpg = new AutoGenerator(abcPath);

		// 全局配置
		final GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(this.getOutputDir());
		gc.setFileOverride(true);
		gc.setActiveRecord(true);
		gc.setEnableCache(false);// XML 二级缓存
		gc.setBaseResultMap(true);// XML ResultMap
		gc.setBaseColumnList(false);// XML columList
		gc.setAuthor(this.getAuthor());
		gc.setOpen(false) ; 

		gc.setServiceName("%sService");
		mpg.setGlobalConfig(gc);

		// 数据源配置
		final DataSourceConfig dsc = new DataSourceConfig();
		dsc.setDbType(dbType);
		dsc.setDriverName(this.getDriverName());
		dsc.setUsername(this.getUserName());
		dsc.setPassword(this.getUserPassword());
		dsc.setUrl(this.getJdbcUrl());
		mpg.setDataSource(dsc);

		// 策略配置
		final StrategyConfig strategy = new StrategyConfig();
		strategy.setTablePrefix(this.getTablePrefix());// 此处可以修改为您的表前缀
		
		strategy.setControllerMappingHyphenStyle(true) ;

		strategy.setSuperServiceClass("com.linesno.training.core.define.base.BaseService");
		strategy.setSuperServiceImplClass("com.linesno.training.core.define.base.BaseServiceImpl");
		strategy.setSuperEntityClass("com.linesno.training.core.define.base.BaseEntity");

		strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略

		strategy.setInclude(tableNames); // 需要生成的表

		strategy.setSuperControllerClass("com.linesno.training.common.base.BaseController");

		mpg.setStrategy(strategy);

		// 包配置
		final PackageConfig pc = new PackageConfig();
		pc.setParent(this.getParentPackage());
		pc.setModuleName(this.getModuleName());
		pc.setController("controller");
		mpg.setPackageInfo(pc);

		// 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
		final InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				final Map<String, Object> map = new HashMap<String, Object>();
				map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
				this.setMap(map);
			}
		};
		mpg.setCfg(cfg);
		mpg.execute(pc);
		logger.debug("代码生成成功.");

		// 打印注入设置
		//System.err.println(mpg.getCfg().getMap().get("abc"));
	}

	/**
	 * 数组转换成集合
	 * @param tableNames
	 * @return
	 */
	public List<String> toArray(String[] tableNames) {
		List<String> arr = new ArrayList<String>() ; 
		for(String s :tableNames) {
			arr.add(s) ;
		}
		return arr ;
	}

	/**
	 * 
	 */
	public abstract void initTableName();

	public String getDriverName() {
		return driverName;
	}

	public void setDriverName(String driverName) {
		this.driverName = driverName;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public String getJdbcUrl() {
		return jdbcUrl;
	}

	public void setJdbcUrl(String jdbcUrl) {
		this.jdbcUrl = jdbcUrl;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getOutputDir() {
		return outputDir;
	}

	public void setOutputDir(String outputDir) {
		this.outputDir = outputDir;
	}

	public DbType getDbType() {
		return dbType;
	}

	public void setDbType(DbType dbType) {
		this.dbType = dbType;
	}

	public String[] getTablePrefix() {
		return tablePrefix;
	}

	public void setTablePrefix(String[] tablePrefix) {
		this.tablePrefix = tablePrefix;
	}

	public String[] getTableNames() {
		return tableNames;
	}

	public void setTableNames(String[] tableNames) {
		this.tableNames = tableNames;
	}

	public List<String> getArr() {
		return arr;
	}

	public void setArr(List<String> arr) {
		this.arr = arr;
	}

	public String getParentPackage() {
		return parentPackage;
	}

	public void setParentPackage(String parentPackage) {
		this.parentPackage = parentPackage;
	}

	public String getModuleName() {
		return moduleName;
	}

	public void setModuleName(String moduleName) {
		this.moduleName = moduleName;
	}

	public String getSOA_MODULE_PREFIX() {
		return SOA_MODULE_PREFIX;
	}

	public void setSOA_MODULE_PREFIX(String sOA_MODULE_PREFIX) {
		SOA_MODULE_PREFIX = sOA_MODULE_PREFIX;
	}

	public Logger getLogger() {
		return logger;
	}

}
